package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.CategoryAttributeTemplateMapper;
import cn.tedu.csmall.product.mapper.CategoryMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.CategoryAddNewDTO;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.service.ICategoryService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 处理类别业务的实现类
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Service
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private BrandCategoryMapper brandCategoryMapper;
    @Autowired
    private CategoryAttributeTemplateMapper categoryAttributeTemplateMapper;
    @Autowired
    private SpuMapper spuMapper;

    public CategoryServiceImpl() {
        log.info("创建业务对象：CategoryServiceImpl");
    }

    @Override
    public void addNew(CategoryAddNewDTO categoryAddNewDTO) {
        log.debug("开始处理【添加类别】的业务，参数：{}", categoryAddNewDTO);
        // 应该保证此类别的名称是唯一的
        String name = categoryAddNewDTO.getName();
        int count = categoryMapper.countByName(name);
        if (count > 0) {
            String message = "添加类别失败，尝试添加的类别名称【" + name + "】已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 检查父级类别是否存在，并确定depth（深度）的值
        Integer depth = 1;
        CategoryStandardVO parentCategory = null;
        Long parentId = categoryAddNewDTO.getParentId();
        if (parentId != 0) {
            parentCategory = categoryMapper.getStandardById(parentId);
            if (parentCategory == null) {
                String message = "添加类别失败，选定的父级类别不存在！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
            } else {
                depth = parentCategory.getDepth() + 1;
            }
        }

        // 创建Category实体类的对象
        Category category = new Category();
        // 将参数DTO的各属性值复制到实体类对象中
        BeanUtils.copyProperties(categoryAddNewDTO, category);
        category.setDepth(depth);
        category.setIsParent(0); // 所有类别在刚刚添中的那一刻，都【不是】父级类别，后续，添加了它的子级类别后，它才是父级类别
        // 插入数据
        log.debug("即将向数据库中插入数据：{}", category);
        int rows = categoryMapper.insert(category);
        if (rows != 1) {
            String message = "添加类别失败，服务器忙，请稍后再尝试！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }

        // 将此新类别的父级类别（如果存在的话）的isParent更新为1
        if (parentId != 0) {
            if (parentCategory.getIsParent() == 0) {
                Category updateParentCategory = new Category();
                updateParentCategory.setId(parentId);
                updateParentCategory.setIsParent(1);
                rows = categoryMapper.update(updateParentCategory);
                if (rows != 1) {
                    String message = "添加类别失败，更新父级类别状态失败！";
                    log.debug(message);
                    throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                }
            }
        }


    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【根据id删除类别】的业务，参数：{}", id);
        // 检查尝试删除的数据是否存在
        CategoryStandardVO currentCategory = categoryMapper.getStandardById(id);
        if (currentCategory == null) {
            String message = "删除类别失败，尝试删除的类别不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 如果此类别关联了品牌，则不允许删除
        {
            int count = brandCategoryMapper.countByCategory(id);
            if (count > 0) {
                String message = "删除类别失败，当前类别仍关联了类别！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_DELETE, message);
            }
        }

        // 如果此类别关联了属性模板，则不允许删除
        {
            int count = categoryAttributeTemplateMapper.countByCategory(id);
            if (count > 0) {
                String message = "删除类别失败，当前类别仍关联了属性模板！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_DELETE, message);
            }
        }

        // 如果此类别关联了SPU，则不允许删除
        {
            int count = spuMapper.countByCategory(id);
            if (count > 0) {
                String message = "删除类别失败，当前类别仍关联了商品！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_DELETE, message);
            }
        }

        // 执行删除
        log.debug("即将执行删除数据，参数：{}", id);
        int rows = categoryMapper.deleteById(id);
        if (rows != 1) {
            String message = "删除类别失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }

        // 如果删除了当前类别，此类别不是一级类别时，其父级类别已经没有任何子级类别，则需要将父级类别的isParent改为0
        {
            Long parentId = currentCategory.getParentId();
            if (parentId != 0) {
                int count = categoryMapper.countByParentId(parentId);
                if (count == 0) {
                    Category updateParentCategory = new Category();
                    updateParentCategory.setId(parentId);
                    updateParentCategory.setIsParent(0);
                    rows = categoryMapper.update(updateParentCategory);
                    if (rows != 1) {
                        String message = "删除类别失败，更新父级类别状态失败！";
                        log.debug(message);
                        throw new ServiceException(ServiceCode.ERR_UPDATE, message);
                    }
                }
            }
        }
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    @Override
    public void setDisplay(Long id) {
        updateDisplayById(id, 1);
    }

    @Override
    public void setHidden(Long id) {
        updateDisplayById(id, 0);
    }

    @Override
    public List<CategoryListItemVO> list() {
        log.debug("开始处理【查询类别列表】的业务，无参数");
        List<CategoryListItemVO> list = categoryMapper.list();
        return list;
    }

    @Override
    public List<CategoryListItemVO> listByParentId(Long parentId) {
        log.debug("开始处理【根据父级类别查询子级类别列表】的业务，无参数");
        return categoryMapper.listByParentId(parentId);
    }

    private void updateEnableById(Long id, Integer enable) {
        String[] enableText = {"禁用", "启用"};
        log.debug("开始处理【{}类别】的业务，ID：{}，目标状态：{}", enableText[enable], id, enable);
        // 检查数据是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if (queryResult == null) {
            String message = enableText[enable] + "类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查当前状态是否与参数表示的状态相同
        if (queryResult.getEnable().equals(enable)) {
            String message = enableText[enable] + "类别失败，当前类别已经处于" + enableText[enable] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 准备执行更新
        Category category = new Category();
        category.setId(id);
        category.setEnable(enable);
        log.debug("即将修改数据，参数：{}", category);
        int rows = categoryMapper.update(category);
        if (rows != 1) {
            String message = enableText[enable] + "类别失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

    private void updateDisplayById(Long id, Integer isDisplay) {
        String[] displayText = {"隐藏", "显示"};
        log.debug("开始处理【{}类别】的业务，ID：{}，目标状态：{}", displayText[isDisplay], id, isDisplay);
        // 检查数据是否存在
        CategoryStandardVO queryResult = categoryMapper.getStandardById(id);
        if (queryResult == null) {
            String message = displayText[isDisplay] + "类别失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查当前状态是否与参数表示的状态相同
        if (queryResult.getIsDisplay().equals(isDisplay)) {
            String message = displayText[isDisplay] + "类别失败，当前类别已经处于" + displayText[isDisplay] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 准备执行更新
        Category category = new Category();
        category.setId(id);
        category.setIsDisplay(isDisplay);
        log.debug("即将修改数据，参数：{}", category);
        int rows = categoryMapper.update(category);
        if (rows != 1) {
            String message = displayText[isDisplay] + "类别失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }

}
